<template>
  <div
    id="container"
    name="container"
    class="parent page-wrapper p-20 d-flex flex-column div-main"
  >
    <div class="main-header">信访大厅视频安防系统</div>
    <div class="level">
      <el-timeline>
        <el-timeline-item
          v-for="(activity, index) in activities"
          :key="index"
          :color="activity.color"
        >
          <div
            class="custom-timeline-item"
            @click="handleTimelineItemClick(activity)"
          >
            <p :class="[activity.isActive ? 'level-active' : 'level-normal']">
              {{ activity.content }}
            </p>
          </div>
        </el-timeline-item>
      </el-timeline>
    </div>
    <!--  内容-->
    <div class="div-content">
      <div class="div-left">
        <div class="left-top">
          <left-top></left-top>
        </div>
        <div class="left-middle">
          <left-middle></left-middle>
        </div>
        <div class="left-bottom">
          <left-bottom></left-bottom>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import LeftTop from "./LeftTop";
import LeftMiddle from "./LeftMiddle";
import LeftBottom from "./LeftBottom";
import util from "@/utils";
import * as THREE from "three";
import h337 from "heatmap.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import {
  CSS3DRenderer,
  CSS3DObject,
  CSS3DSprite,
} from "three/examples/jsm/renderers/CSS3DRenderer";
export default {
  components: {
    LeftTop,
    LeftMiddle,
    LeftBottom,
  },
  data() {
    return {
      reverse: false,
      activities: [
        {
          content: "选择楼层",
          color: "#35fff4",
          isActive: true,
        },
        {
          content: "五楼(5F)",
          isActive: false,
        },
        {
          content: "四楼(4F)",
          isActive: false,
        },
        {
          content: "三楼(3F)",
          isActive: false,
        },
        {
          content: "二楼(2F)",
          isActive: false,
        },
        {
          content: "一楼(1F)",
          isActive: false,
        },
        {
          content: "负一楼(B1)",
          isActive: false,
        },
      ],
      show: true,
      scene: null,
      texture: null,
      progress: 0.0,
      current: -1,
      gltfModel: null,
      mark: null,
      building: null,
      fst: [],
      sec: [],
      thd: [],
      floor1: new THREE.Group(),
      floor2: new THREE.Group(),
      floor3: new THREE.Group(),
      dir: null,
      dirTo: null,
      subM: null,
      mov: [
        { dir: "x", value: 3 },
        { dir: "x", value: -3 },
        { dir: "z", value: 13 },
        { dir: "z", value: -8 },
        { dir: "x", value: -9 },
      ],
      lastTime: 0,
      clock: new THREE.Clock(),
      speed: 0.2,
      scale: 0.11,
      circleMesh: null,
      ringMesh: null,
    };
  },
  mounted() {
    this.init();
    this.loadModel("xf-prod.glb");
    this.createHeatmap();
    this.addHeatmapToScene();
    this.animate();
  },
  methods: {
    init() {
      this.scene = new THREE.Scene();
      this.cssScene = new THREE.Scene();

      //初始化渲染器
      let container = document.getElementById("container");
      let height = container.offsetHeight;
      let width = container.offsetWidth;

      // 初始化相机
      this.camera = new THREE.PerspectiveCamera(
        50,
        width / height,
        0.01,
        10000
      );

      this.camera.position.set(47, 15, 29);
      this.camera.rotation.set(-Math.PI / 7, Math.PI / 4, Math.PI / 10);
      this.camera.lookAt(0, 0, 0);
      this.scene.add(this.camera);

      let hLight = new THREE.AmbientLight(0xffffff, 10);
      this.scene.add(hLight);

      // let light1 = new THREE.DirectionalLight(0xffffff, 10);
      // light1.position.set(50, 50, 50);
      // this.scene.add(light1);

      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true,
        logarithmicDepthBuffer: true,
      });
      this.renderer.setSize(width, height);
      container.appendChild(this.renderer.domElement);

      //初始化控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);

      this.controls.minDistance = 10;
      this.controls.maxDistance = 500;
      // // 上下旋转范围
      this.controls.minPolarAngle = 0; // radians
      this.controls.maxPolarAngle = Math.PI * 0.5; // radians
      // // 左右旋转范围

      window.addEventListener("resize", this.onWindowResize, false);
    },
    onWindowResize() {
      let container = document.getElementById("container");
      let height = container.offsetHeight;
      let width = container.offsetWidth;

      this.camera.aspect = width / height;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(width, height);
    },
    loadModel(modelName) {
      let that = this;
      const loader = new GLTFLoader();
      loader.setPath("/model/");

      var mats = new THREE.MeshBasicMaterial({
        color: 0xababab,
        transparent: false,
        opacity: 0.9,
      });
      var matGlow = new THREE.MeshStandardMaterial({
        color: 0xffffff,
        metalness: 1,
        roughness: 0,
        transparent: true,
        opacity: 0.6,
      });
      loader.load(modelName, (gltf) => {
        if (modelName == "mark.glb") {
          this.mark = gltf.scene;
          // 对模型进行放大
          this.mark.scale.set(20, 20, 20); // 按照需要的倍数进行放大
          this.mark.rotation.y = 0;
          this.mark.position.set(0, 0, 0);
          this.scene.add(this.mark);
        } else {
          gltf.scene.traverse(function (child) {
            if (child.isMesh) {
              if (
                child.name.includes("wall") ||
                child.name.includes("stair") ||
                child.name.includes("screen") ||
                child.name.includes("desk") ||
                child.name.includes("pillar") ||
                child.name.includes("slope") ||
                child.name.includes("chair")
              ) {
                console.log(child.name);
                // child.material = matGlow;

                const edges = new THREE.EdgesGeometry(child.geometry);
                const lineMaterial = new THREE.LineBasicMaterial({
                  color: 0xfffffff,
                  linewidth: 1,
                });
                const edgesMesh = new THREE.LineSegments(edges, lineMaterial);
                that.scene.add(edgesMesh);
              }
            }
          });
          this.building = gltf.scene;
          // 对模型进行放大
          this.scene.add(this.building);
          this.createTag();
        }
      });
    },

    createHeatmap() {
      // 创建热力图实例
      this.heatmap = h337.create({
        container: document.createElement("div"),
        radius: 50, // 点的半径
        maxOpacity: 0.6,
        minOpacity: 0,
        blur: 0.9,
        gradient: {
          0.4: "blue",
          0.6: "green",
          0.8: "yellow",
          1: "red",
        },
      });

      // 模拟一些数据点
      this.points = [];
      for (let i = 0; i < 100; i++) {
        this.points.push({
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          value: Math.random() * 100,
        });
      }

      // 将数据添加到热力图中
      this.heatmap.setData({
        max: 100,
        min: 0,
        data: this.points,
      });
    },

    addHeatmapToScene() {
      // 创建一个简单的几何体用来显示热力图
      const geometry = new THREE.PlaneGeometry(10, 10, 10, 10);
      const material = new THREE.MeshBasicMaterial({
        color: 0xffffff,
        side: THREE.DoubleSide,
        map: this.createTextureFromHeatmap(),
      });
      this.mesh = new THREE.Mesh(geometry, material);
      this.scene.add(this.mesh);
    },

    createTextureFromHeatmap() {
      // 从 heatmap.js 创建的热力图数据生成纹理
      const canvas = this.heatmap._renderer.canvas;
      const texture = new THREE.CanvasTexture(canvas);
      return texture;
    },

    animate() {
      requestAnimationFrame(this.animate);

      const elapsedTime = this.clock.getElapsedTime();

      // 检查是否已经过了1秒
      if (elapsedTime - this.lastTime >= 0.15) {
        this.mesh.material.map = this.createTextureFromHeatmap();
        this.mesh.material.needsUpdate = true;
        this.renderer.render(this.scene, this.camera);
        this.trace();
        // 更新 lastTime
        this.lastTime = elapsedTime;
      }
    },

    trace() {
      if (this.ringMesh) {
        if (this.ringMesh.position.x > 15 || this.ringMesh.position.x < 5) {
          this.speed = -this.speed;
        }
        this.circleMesh.position.x += this.speed;
        this.ringMesh.position.x += this.speed;
        if (this.ringMesh.scale.x > 1.5) {
          this.ringMesh.scale.x = 1;
          this.ringMesh.scale.y = 1;
        }
        this.ringMesh.scale.x += this.scale;
        this.ringMesh.scale.y += this.scale;
      }
    },
    createTag() {
      // 创建圆形几何体
      const radius = 0.3; // 圆的半径
      const segments = 32; // 圆的细分段数
      const circleGeometry = new THREE.CircleGeometry(radius, segments);

      // 创建材质
      const material = new THREE.MeshBasicMaterial({
        color: 0xff0000,
        side: THREE.DoubleSide,
      }); // 颜色为黄色，双面材质

      // 创建圆形网格
      this.circleMesh = new THREE.Mesh(circleGeometry, material);
      this.circleMesh.rotation.x = Math.PI / 2;
      this.circleMesh.position.set(5, 1.3, 10);
      this.scene.add(this.circleMesh);

      // 创建环形几何体
      const innerRadius = 0.4; // 内半径
      const outerRadius = 0.5; // 外半径
      const ringGeometry = new THREE.RingGeometry(
        innerRadius,
        outerRadius,
        segments
      );

      // 创建环形网格
      this.ringMesh = new THREE.Mesh(ringGeometry, material);
      this.ringMesh.rotation.x = Math.PI / 2;
      this.ringMesh.position.set(5, 1.3, 10);
      this.scene.add(this.ringMesh);
    },
    addClass(index, event) {
      this.current = index;
      console.log(index);
    },
    handleTimelineItemClick(item) {
      for (let i = 0; i < this.activities.length; i++) {
        this.activities[i].color = "#ffffff";
        this.activities[i].isActive = false;
      }
      item.isActive = true;
      item.color = "#35fff4";
    },
    test() {},
  },
};
</script>

<style lang="less">
.parent {
  font-size: 14px;
  height: 100%;
  //   background: #ababab;
  background: url("/img/t_bg.png") no-repeat center;
  border-radius: 20px;
  background-size: 100% 100%;
  width: 100%;
}
.main-header {
  width: calc(100% - 300px);
  height: 100px;
  position: absolute;
  top: 100px;
  background: url("/img/title_bg.png") no-repeat center;
  background-size: 100% 100%;
  color: #aabbdd;
  text-align: center;
  font-size: 47px;
  line-height: 60px;
  letter-spacing: 10px;
  font-weight: bolder;
}
.info {
  height: 150px;
  width: 300px;
  background: url("/img/panel.png") no-repeat center;
  background-size: 100% 100%;
  position: absolute;
}
.info-title {
  font-size: 16px;
  height: 55px;
  line-height: 60px;
  color: aliceblue;
  text-align: center;
}
.info-pic {
  padding: 10px 50px 10px 50px;
  color: aliceblue;
  display: flex;
}
.info-pic img {
  height: 60px;
  width: 60px;
}
.info-div {
  font-size: 13px;
  width: 130px;
  height: 60px;
  display: block;
  padding: 20px 0px 0px 30px;
}
.info-div div {
  height: 50%;
  line-height: 50%;
}

.info-detail {
  padding: 5px 50px 2px 50px;
  font-size: 13px;
  height: 30px;
  line-height: 23px;
  text-align: left;
  color: #02fe90;
}

.info-detail span {
  color: #02fe90;
  margin-left: 1.5rem;
}
.info-title:after {
  position: absolute;
  content: "";
  width: 80%;
  height: 1px;
  background: -webkit-linear-gradient(
    left,
    rgba(0, 216, 247, 0),
    #00afed,
    rgba(0, 216, 246, 0)
  );
  left: 50%;
  transform: translateX(-50%);
  top: 55px;
}

#menu {
  display: flex;
  cursor: pointer;
  transition: all 0.5s;
}
#menu li {
  font-size: 13px;
  width: 100px;
  height: 30px;
  line-height: 30px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  box-sizing: border-box;
  border-radius: 3px;
  text-align: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.3);
  margin-right: 2px;
}

#menu li:hover {
  background-color: rgba(255, 255, 255, 0.5) !important;
}

#menu li:active {
  background-color: #1abc9c !important;
  color: black;
}
.blue {
  background-color: #1abc9c !important;
  color: white;
}

.level {
  position: absolute;
  right: 50px;
  top: 190px;
}
.level-active {
  color: #35fff4;
  font-weight: bold;
  height: 35px;
}
.level-normal {
  color: white;
  height: 35px;
}

.div-content {
  height: calc(100% - 280px);
  margin-top: 100px;
  display: flex;
  width: 20%;
  min-width: 300px;
  position: absolute;
  padding: 0px 20px;
  border-radius: 10px;
  background-color: rgba(72, 80, 93, 0.3);
}

.div-left {
  height: 100%;
  width: 100%;
  min-width: 300px;
  display: block;
  padding-top: 10px;
}
.left-top {
  height: 20%;
}

.left-bottom {
  margin-top: 20px;
}
</style>
